package cn.good.yan.service.t5;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * 5 布隆过滤器  Guava
 *      案例：如果黑名单比较：
 *          先去布隆过滤器，查询是否存在，存在代表之前新增过， 存在：不再推送直接返回
 *                             不存在，进行推荐，再新增进黑名单中，布隆过滤器中
 *                                    进行新增数据库
 * @author shengren.yan
 * @create 2023-11-27
 */
@Service
@Slf4j
public class GuavaService {

    // 1.定义一个常量
    public static final int _1W = 10000;
    // 2.定义我们guava布隆过滤器，初始容量  100万
    public static final int SIZE = 100 * _1W;
    // 3.误判率，它越小误判的个数也越少  值越小，hash函数越多，bitmap占用的位越多，默认是 0.03 需要5个hash函数 ，0.01 需要 7个函数
    public static double fpp = 0.03;
    // 4.创建guava布隆过滤器
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE, fpp);

    public void guava() {
        // 1.先让bloomFilter加入100w白名单数据 - 进行初始化
        for (int i = 0; i < SIZE; i++) {
            bloomFilter.put(i);
        }
        // 2.故意取10w个不在合法范围内的数据，来进行误判率的演示  ，数组长度为10万，不在布隆过滤器里
        ArrayList<Integer> list = new ArrayList<>(10 * _1W);

        // 3.验证 ，模拟循环 10W个新集合
        for (int i = SIZE + 1; i < SIZE + (10 * _1W); i++){
            if (bloomFilter.mightContain(i)){
                log.info("被误判了:{}", i);
                list.add(i);
            }
        }
        log.info("误判总数量：{}", list.size()); // 结果是 3033
    }


}
